package com.zhexiao.convert.utils;

import com.zhexiao.convert.entity.dto.ConvertDTO;
import com.zhexiao.convert.entity.model.CellContent;
import com.zhexiao.convert.entity.model.ColumnContent;
import com.zhexiao.convert.entity.model.ParagraphStyle;
import com.zhexiao.convert.entity.model.RunStyle;
import com.zhexiao.convert.entity.postman.Item;
import com.zhexiao.convert.entity.postman.Parameter;
import com.zhexiao.convert.entity.postman.Postman;
import com.zhexiao.convert.entity.postman.Response;
import org.apache.poi.xwpf.usermodel.ParagraphAlignment;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.List;

/**
 * @author zhe.xiao
 * @date 2021-02-07 9:45
 */
public class PostmanWord extends Word {
    private static final Logger log = LoggerFactory.getLogger(PostmanWord.class);

    private Postman postman;

    //接口标题
    private static final String[] API_TITLE = {"接口名称", "接口URL", "接口功能", "请求方式", "调用系统", "数据格式", "参数", "返回值", "返回示例", "调用举例", "异常场景"};


    public PostmanWord(Postman postman) {
        super();
        this.postman = postman;
    }

    public ColumnContent getApiTitle() {
        //接口标题
        RunStyle columnDataStyle = new RunStyle().setFontFamily("微软雅黑").setFontSize(9);
        CellContent[] cellTitle = new CellContent[API_TITLE.length];
        for (int i = 0; i < API_TITLE.length; i++) {
            CellContent cellContent = new CellContent().setRunStyle(columnDataStyle).setContent(API_TITLE[i]);
            cellTitle[i] = cellContent;
        }

        return new ColumnContent().setColumnNum(0).setColumnData(cellTitle);
    }

    public PostmanWord generate(ConvertDTO convertDTO) {
        //大标题
        Word.ParagraphBuilder.builder(this).setText("API接口文档 - " + postman.getInfo().getName())
                .setParagraphStyle(new ParagraphStyle().setAlignment(ParagraphAlignment.CENTER).setBold(true).setFontSize(18))
                .build();

        //接口标题
        ColumnContent apiTitle = getApiTitle();

        //接口内容
        List<Item> items = postman.getItem();
        for (Item item : items) {
            CellContent[] cellData = this.contentColumn(item, convertDTO);
            ColumnContent contentData = new ColumnContent().setColumnNum(1).setColumnData(cellData);

            //生成表格
            Word.TableBuilder.builder(this)
                    .setRowNum(11)
                    .setColumnNum(2)
                    .setColumnContent(apiTitle)
                    .setColumnContent(contentData)
                    .build();

            this.addBreak();
        }
        log.info("---------------word表格创建完毕--------------");
        return this;
    }

    /**
     * 读取接口内容
     *
     * @param item
     * @param convertDTO
     * @return
     */
    private CellContent[] contentColumn(Item item, ConvertDTO convertDTO) {
        //得到接口URL
        StringBuilder url = new StringBuilder();
        try {
            url.append(item.getRequest().getUrl().getHost().get(0));
            List<String> path = item.getRequest().getUrl().getPath();
            if (!path.isEmpty()) {
                path.stream().forEach(e -> {
                    url.append("/");
                    url.append(e);
                });
            }
        } catch (Exception e) {
            log.error("item={}", item);
        }


        //参数解析，分GET和POST两种
        List<Parameter> parameters;
        StringBuilder paramsSb = new StringBuilder();
        try {
            if (!StringUtils.isEmpty(item.getRequest().getBody())) {
                String jsonBody = item.getRequest().getBody().getRaw();
                parameters = this.parsePostmanRequestBody(jsonBody);
            } else {
                parameters = item.getRequest().getUrl().getQuery();
            }

            if (parameters != null && !parameters.isEmpty()) {
                parameters.forEach(parameter -> {
                    paramsSb.append(parameter.getKey() + "  [" + parameter.getValue() + "] <br>");
                });
            }
        } catch (Exception e) {
            log.error("item={}", item);
        }

        //返回数据结构
        StringBuilder responseSb = new StringBuilder();
        if (item.getResponse() != null && !item.getResponse().isEmpty()) {
            List<Response> responses = item.getResponse();
            responses.forEach(response -> {
                String responseBody = response.getBody();

                //格式化返回数据,主要是加换行
                String[] respStrList = responseBody.split("\n");
                for (String s : respStrList) {
                    String s1 = s + "<br>";
                    responseSb.append(s1);
                }
            });
        }

        //数据
        String[] contentData = new String[]{
                item.getName(),
                url.toString(),
                item.getName(),
                item.getRequest().getMethod(),
                convertDTO.getCallSystem(),
                convertDTO.getDataFormat(),
                paramsSb.toString(),
                convertDTO.getReturns(),
                responseSb.toString(),
                item.getRequest().getUrl().getRaw(),
                ""
        };

        RunStyle columnDataStyle = new RunStyle().setFontFamily("微软雅黑").setFontSize(9).setColor("333333");
        CellContent[] cellContents = new CellContent[contentData.length];
        for (int i = 0; i < contentData.length; i++) {
            CellContent cellContent = new CellContent().setRunStyle(columnDataStyle).setContent(contentData[i]);
            cellContents[i] = cellContent;
        }

        return cellContents;
    }


    /**
     * 解析POST请求的JSON参数
     *
     * @param jsonBody
     * @return
     */
    private List<Parameter> parsePostmanRequestBody(String jsonBody) {
        ArrayList<Parameter> parameters = new ArrayList<>();
        if (StringUtils.isEmpty(jsonBody)) {
            return parameters;
        }

        String newStr = jsonBody.replaceAll("[{}\r\n\\s]", "");
        String[] paramsParis = newStr.split("[,]");

        for (String paris : paramsParis) {
            String[] parisKV = paris.split(":");

            Parameter parameter = new Parameter().setKey(parisKV[0]).setValue(parisKV[1]);
            parameters.add(parameter);
        }

        return parameters;

    }
}
